package vm;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 庄子斌
 * @since 2021-02-01
 */
public class TestUtil<T, R> {
  private final List<T> source;
  private final Function<List<T>, List<R>> mission;

  public TestUtil(List<T> source,
      Function<List<T>, List<R>> mission) {
    this.source = source;
    this.mission = mission;
  }

  public static <T, R> List<R> execute(List<T> source, Function<List<T>, List<R>>mission) {
    return new TestUtil<T, R>(source, mission).execute();
  }

  private List<R> execute() {
    final List<CompletableFuture<List<R>>> futureList = new ArrayList<>();
    for (int i = 0; i < 2; i++) {
      futureList.add(CompletableFuture.supplyAsync(() ->mission.apply(source)));
    }

    /* 聚合所有结果 */
    return CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{}))
        .thenApply(v -> futureList.stream().flatMap(data -> {
          try {
            return data.get().stream();
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        }).collect(Collectors.toUnmodifiableList())).join();
  }
}
